﻿using ff14bot.Behavior;
using ff14bot.Enums;
using ff14bot.Managers;
using System.Linq;
using TreeSharp;
using Magitek.Helpers;
using ff14bot;
using ff14bot.Objects;
using Action = TreeSharp.Action;
using ff14bot.Helpers;

namespace Magitek.Rotations
{
    public class Scholar : Magitek
    {
        public override float PullRange { get { return WindowSettings.ScholarPullRange; } }
        public override ClassJobType[] Class { get { return new ClassJobType[] { ClassJobType.Scholar }; } }

        #region Pulling & Resting
        protected override Composite CreatePull()
        {
            return Combat.CreatePull(25);
        }

        protected override Composite CreateRest()
        {
            return Extensions.DefaultRestBehavior(r => Core.Player.CurrentManaPercent);
        }
        #endregion
        #region Buffs // Mainly used for Grindbot etc...
        protected override Composite CreatePreCombatBuffs()
        {
            return new PrioritySelector(
                Extensions.SummonChocobo()
                );
        }
        protected override Composite CreateCombatBuffs()
        {
            return new PrioritySelector(
                new Decorator(r => Core.Player.IsCasting, new ActionAlwaysSucceed())
            );
        }
        #endregion
        #region Combat
        protected override Composite CreateHeal()
        {
            return
                new PrioritySelector(
                
                new Decorator(r => WindowSettings.ScholarLetMagitekControlPet, Extensions.PetFollow),

                PartyHelper.AcquireTargetInformation(),

                new Decorator(r => Core.Player.Pet != null && WindowSettings.ScholarLetMagitekControlPet && Pet.PetMode == PetMode.Sic, new Action(r => Pet.DoAction("Obey", Core.Player.Pet))),
                new Decorator(r => Core.Player.Pet != null && !WindowSettings.ScholarLetMagitekControlPet && Pet.PetMode == PetMode.Obey, new Action(r => Pet.DoAction("Sic", Core.Player.Pet))),
       
                Casting.PetCast(r => Core.Player.Pet, r => "Fey Covenant", r => WindowSettings.ScholarLetMagitekControlPet && PartyHelper.PartyMembersNeedingHealsPet(70) >= 3),
                Casting.PetCast(r => Core.Player.Pet, r => "Fey Illumination", r => WindowSettings.ScholarLetMagitekControlPet && Core.Player.Location.Distance(Core.Player.Pet.Location) <= 15 && PartyHelper.Healtarget != null && PartyHelper.Healtarget.CurrentHealthPercent <= 50 && PartyHelper.IsTank(PartyHelper.Healtarget)),
                Casting.PetCast(r => PartyHelper.Healtarget, r => "Embrace", r => WindowSettings.ScholarLetMagitekControlPet && PartyHelper.Healtarget != null && PartyHelper.Healtarget.CurrentHealthPercent <= 95 && PartyHelper.IsTank(PartyHelper.Healtarget)),
                Casting.PetCast(r => Core.Player.Pet, r => "Whispering Dawn", r => WindowSettings.ScholarLetMagitekControlPet && PartyHelper.PartyMembersNeedingHealsPet(80) >= 3),
                Casting.PetCast(r => PartyHelper.Healtarget, r => "Embrace", r => WindowSettings.ScholarLetMagitekControlPet && PartyHelper.Healtarget != null && PartyHelper.Healtarget.CurrentHealthPercent <= 80),
                Casting.Cast(r => "Rouse", r => PartyHelper.Healtarget != null && PartyHelper.Healtarget.CurrentHealthPercent <= WindowSettings.ScholarRouseHp, r => Core.Player, r => 3, r => false),

                new Decorator(r => Core.Player.IsCasting, new ActionAlwaysSucceed()),

                new Decorator(ret =>
                {
                    if (!WindowSettings.ScholarSwiftcastRez)
                        return false;

                    if (Core.Player.HasAura("Swiftcast"))
                        return true;

                    return true;

                }, new PrioritySelector(

                    Casting.Cast(r => "Resurrection", r => WindowSettings.ScholarSwiftcastRez && Core.Player.InCombat && PartyHelper.Deadtarget != null && Core.Player.HasAura("Swiftcast") && Core.Player.InCombat, r => PartyHelper.Deadtarget, r => 3, r => false),
                    Casting.Cast(r => "Summon", r => Core.Player.Pet == null && WindowSettings.ScholarUseEos && Core.Player.HasAura("Swiftcast"), r => Core.Player, r => 4, r => false),
                    Casting.Cast(r => "Summon II", r => Core.Player.Pet == null && WindowSettings.ScholarUseSelene && Core.Player.HasAura("Swiftcast"), r => Core.Player, r => 4, r => false)

                    )),


                #region In Party Code
                    new Decorator(ret =>
                    {

                    if (!PartyManager.IsInParty)
                        return false;

                    if (Core.Player.HasAura("Swiftcast"))
                        return false;

                    return true;

                    },

                new PrioritySelector(

                Combat.DoPVPHealing(),

                Casting.Cast(r => "Summon", r => !Core.Player.InCombat && Core.Player.Pet == null && WindowSettings.ScholarUseEos && WindowSettings.lastspellused != "Summon", r => Core.Player, r => 4, r => false),
                Casting.Cast(r => "Summon II", r => !Core.Player.InCombat && Core.Player.Pet == null && WindowSettings.ScholarUseSelene && WindowSettings.lastspellused != "Summon II", r => Core.Player, r => 4, r => false),
                Casting.Cast(r => "Summon", r => Core.Player.Pet == null && WindowSettings.ScholarUseEos && Core.Player.HasAura("Swiftcast"), r => Core.Player, r => 4, r => false),
                Casting.Cast(r => "Summon II", r => Core.Player.Pet == null && WindowSettings.ScholarUseSelene && Core.Player.HasAura("Swiftcast"), r => Core.Player, r => 4, r => false),
                Casting.Cast(r => "Swiftcast", r => WindowSettings.ScholarSwiftcastRez && Core.Player.InCombat && PartyHelper.Deadtarget != null, r => Core.Player, r => 4, r => false),
                Casting.Cast(r => "Resurrection", r => PartyHelper.Deadtarget != null && !Core.Player.InCombat, r => PartyHelper.Deadtarget, r => 10, r => false),
                Casting.Cast(r => "Resurrection", r => WindowSettings.ScholarSwiftcastRez && Core.Player.InCombat && PartyHelper.Deadtarget != null && Actionmanager.CanCast("Resurrection", PartyHelper.Deadtarget) && Core.Player.HasAura("Swiftcast") && Core.Player.InCombat, r => PartyHelper.Deadtarget, r => 3, r => false),
                Casting.Cast(r => "Aetherflow", r => !Core.Player.HasAura("Aetherflow") && Core.Player.CurrentManaPercent <= WindowSettings.ScholarAetherflowMp, r => Core.Player, r => 3, r => false),
                Casting.Cast(r => "Energy Drain", r => WindowSettings.ScholarUseEnergyDrain && Core.Player.HasTarget && Core.Player.CurrentTarget.CanAttack && Core.Player.HasAura("Aetherflow") && Core.Player.CurrentManaPercent <= WindowSettings.ScholarEnergyDrainMana, r => Core.Player.CurrentTarget, r => 3, r => false),
                Casting.Cast(r => "Energy Drain", r => WindowSettings.ScholarUseEnergyDrain && PartyHelper.Healtarget != null && PartyHelper.IsTank(PartyHelper.Healtarget) && Core.Player.HasAura("Aetherflow") && Core.Player.CurrentManaPercent <= WindowSettings.ScholarEnergyDrainMana, r => GameObjectManager.GetObjectsOfType<BattleCharacter>().Where(u => u.ObjectId == PartyHelper.Healtarget.CurrentTargetId).FirstOrDefault(), r => 3, r => false),
                Casting.Cast(r => "Eye for an Eye", r => PartyHelper.Eyeforaneyetarget != null && PartyHelper.Eyeforaneyetarget.CurrentHealthPercent <= 60, r => PartyHelper.Eyeforaneyetarget, r => 3, r => false),
                Casting.Cast(r => "Presence of Mind", r => PartyHelper.Healtarget != null && PartyHelper.Healtarget.CurrentHealthPercent < 25, r => Core.Player, r => 3, r => false),
                Casting.Heal(r => "Lustrate", r => WindowSettings.ScholarUseLustrate && PartyHelper.Healtarget != null && PartyHelper.IsTank(PartyHelper.Healtarget) && PartyHelper.Healtarget.CurrentHealthPercent < WindowSettings.ScholarTankLustrateHp, r => PartyHelper.Healtarget, r => 3, r => true),
                Casting.Heal(r => "Lustrate", r => WindowSettings.ScholarUseLustrate && PartyHelper.Healtarget != null && PartyHelper.Healtarget.CurrentHealthPercent < WindowSettings.ScholarLustrateHp, r => PartyHelper.Healtarget, r => 3, r => true),
                Casting.Cast(r => "Leeches", r => PartyHelper.Dispeltarget != null, r => PartyHelper.Dispeltarget, r => 3, r => false),
                new Decorator(r =>
                {

                    if (!WindowSettings.ScholarUseSacredSoil)
                        return false;

                    if (PartyHelper.Healtarget == null)
                        return false;

                    if (PartyHelper.Healtarget.HasAura("Sacred Soil"))
                        return false;

                    if (!Core.Player.HasAura("Aetherflow"))
                        return false;

                    if (PartyHelper.PeopleNeedingHealsAroundTarget(WindowSettings.ScholarSacredSoilHp, PartyHelper.Healtarget) < Magitek.WindowSettings.TargetsToAOEHeal)
                        return false;

                    return true;

                }, new Action(r => { Actionmanager.DoActionLocation("Sacred Soil", PartyHelper.Healtarget.Location); Logging.Write("[Magitek] Using Sacred Soil"); })),

                Casting.Cast(r => "Succor", r => PartyHelper.PartyMembersNeedingHeals(WindowSettings.ScholarSuccorHp, 15) >= Magitek.WindowSettings.TargetsToAOEHeal,
                r => Core.Player, r => 5, r => true),
                Casting.Heal(r => "Adloquium", r => PartyHelper.Healtarget != null && PartyHelper.IsTank(PartyHelper.Healtarget) && !PartyHelper.Healtarget.HasAura("Galvanize", true) && PartyHelper.Healtarget.CurrentHealthPercent <= WindowSettings.ScholarTankAdloquiumHp, r => PartyHelper.Healtarget, r => 3, r => true),
                Casting.Heal(r => "Adloquium", r => PartyHelper.Healtarget != null && !PartyHelper.Healtarget.HasAura("Galvanize", true) && PartyHelper.Healtarget.CurrentHealthPercent <= WindowSettings.ScholarAdloquiumHp, r => PartyHelper.Healtarget, r => 3, r => true),
                Casting.Heal(r => "Physick", r => PartyHelper.Healtarget != null && PartyHelper.IsTank(PartyHelper.Healtarget) && PartyHelper.Healtarget.CurrentHealthPercent <= WindowSettings.ScholarTankPhysickHp, r => PartyHelper.Healtarget, r => 3, r => true),
                Casting.Heal(r => "Physick", r => PartyHelper.Healtarget != null && PartyHelper.Healtarget.CurrentHealthPercent <= WindowSettings.ScholarPhysickHp, r => PartyHelper.Healtarget, r => 3, r => true),
                Casting.Cast(r => "Protect", r => WindowSettings.lastspellused != "Swiftcast" && WindowSettings.ScholarProtectOOC && !Core.Player.InCombat && PartyHelper.Healtarget != null && !PartyHelper.Healtarget.HasAura("Protect") && PartyHelper.Healtarget.CurrentJob != ClassJobType.Adventurer, r => PartyHelper.Healtarget, r => 3, r => true),
                Casting.Cast(r => "Stoneskin", r => WindowSettings.lastspellused != "Swiftcast" && WindowSettings.ScholarProtectOOC && !Core.Player.InCombat && PartyHelper.Healtarget != null && !PartyHelper.Healtarget.HasAura("Stoneskin") && PartyHelper.Healtarget.CurrentJob != ClassJobType.Adventurer, r => PartyHelper.Healtarget, r => 3, r => true),
                Casting.Cast(r => "Sustain", r => Core.Player.Pet != null && Core.Player.Pet.CurrentHealthPercent <= WindowSettings.ScholarSustainHp && !Core.Player.Pet.HasAura("Sustain"), r => Core.Player.Pet, r => 3, r => true),
                Casting.Heal(r => "Adloquium", r => Core.Player.Pet != null && !Core.Player.Pet.HasAura("Galvanize", true) && Core.Player.Pet.CurrentHealthPercent <= WindowSettings.ScholarPetAdloquiumHp, r => Core.Player.Pet, r => 3, r => true),
                Casting.Cast(r => "Physick", r => Core.Player.Pet != null && Core.Player.Pet.CurrentHealthPercent <= WindowSettings.ScholarPetPhysickHp, r => Core.Player.Pet, r => 3, r => true),
                Casting.Cast(r => "Virus", r => Core.Player.HasTarget && WindowSettings.ScholarUseVirus && !Core.Player.CurrentTarget.HasAura("Virus") && Core.Player.CurrentTarget.CanAttack, r => Core.Player.CurrentTarget, r => 3, r => false),
                Casting.Heal(r => "Adloquium", r => WindowSettings.HealEveryone && PartyHelper.Alliancehealtarget != null && PartyHelper.Alliancehealtarget.CurrentHealthPercent <= WindowSettings.ScholarAdloquiumHp && !PartyHelper.Alliancehealtarget.HasAura("Galvanize", true), r => PartyHelper.Alliancehealtarget, r => 4, r => true),
                Casting.Heal(r => "Physick", r => WindowSettings.HealEveryone && PartyHelper.Alliancehealtarget != null && PartyHelper.Alliancehealtarget.CurrentHealthPercent <= WindowSettings.ScholarPhysickHp, r => PartyHelper.Alliancehealtarget, r => 4, r => true))),
                    #endregion
                #region Solo
                new Decorator(ret =>
                {

                    if (!Core.Player.HasTarget)
                        return false;

                    if (!Core.Player.InCombat)
                        return false;

                    if (!Core.Player.CurrentTarget.CanAttack)
                        return false;

                    if ((WindowSettings.ScholarDoDPS && Core.Player.CurrentManaPercent >= WindowSettings.ScholarStopDPSMana) || !PartyManager.IsInParty || WindowSettings.SoloMode)
                        return true;

                    return false;

                }, CreateCombat()),

                Casting.Cast(r => "Cleric Stance", r => (WindowSettings.SoloMode && !Core.Player.HasAura("Cleric Stance")), r => Core.Player, r => 3, r => false),
                Casting.Cast(r => "Swiftcast", r => (PartyHelper.Healtarget != null && PartyHelper.Healtarget.CurrentHealth == 0) || Core.Player.Pet == null, r => Core.Player, r => 4, r => false),
                Casting.Cast(r => "Summon", r => Core.Player.Pet == null && WindowSettings.ScholarUseEos && Core.Player.HasAura("Swiftcast"), r => Core.Player, r => 4, r => false),
                Casting.Cast(r => "Summon II", r => Core.Player.Pet == null && WindowSettings.ScholarUseSelene && Core.Player.HasAura("Swiftcast"), r => Core.Player, r => 4, r => false),
                Casting.Cast(r => "Aetherflow", r => !Core.Player.HasAura("Aetherflow") && Core.Player.CurrentManaPercent <= WindowSettings.ScholarAetherflowMp, r => Core.Player, r => 3, r => false),
                Casting.Cast(r => "Protect", r => WindowSettings.lastspellused != "Swiftcast" && !Core.Player.HasAura("Swiftcast") && WindowSettings.ScholarProtectOOC && !Core.Player.InCombat && !Core.Player.HasAura("Protect"), r => Core.Player, r => 3, r => true),
                Casting.Cast(r => "Stoneskin", r => WindowSettings.lastspellused != "Swiftcast" && !Core.Player.HasAura("Swiftcast") && WindowSettings.ScholarStoneskinOOC && !Core.Player.InCombat && !Core.Player.HasAura("Stoneskin"), r => Core.Player, r => 3, r => true),
                Casting.Cast(r => "Adloquium", r => !Core.Player.HasAura("Galvanize", true) && Core.Player.CurrentHealthPercent <= WindowSettings.ScholarAdloquiumHp, r => Core.Player, r => 3, r => false),
                Casting.Cast(r => "Physick", r => Core.Player.CurrentHealthPercent < WindowSettings.ScholarPhysickHp, r => Core.Player, r => 3, r => false),
                Casting.Cast(r => "Sustain", r => Core.Player.Pet != null && Core.Player.Pet.CurrentHealthPercent <= WindowSettings.ScholarSustainHp && !Core.Player.Pet.HasAura("Sustain"), r => Core.Player.Pet, r => 3, r => true),
                Casting.Heal(r => "Adloquium", r => Core.Player.Pet != null && !Core.Player.Pet.HasAura("Galvanize", true) && Core.Player.Pet.CurrentHealthPercent <= WindowSettings.ScholarPetAdloquiumHp, r => Core.Player.Pet, r => 3, r => true),
                Casting.Cast(r => "Physick", r => Core.Player.Pet != null && Core.Player.Pet.CurrentHealthPercent <= WindowSettings.ScholarPetPhysickHp, r => Core.Player.Pet, r => 3, r => true)

                );
                #endregion


        }
        public bool HasDots()
        {
            if (Core.Player.CurrentTarget.HasAura("Bio", true, 3000) &&
                Core.Player.CurrentTarget.HasAura("Bio II", true, 3000) &&
                Core.Player.CurrentTarget.HasAura("Miasma", true, 3000))
                return true;

            return false;
        }

        public int MiasmaII()
        {
            return Extensions.UnfriendlyUnits.Count(u => !u.HasAura("Miasma II", true) && u.Location.Distance(Core.Player.Location) < 6);
        }

        public int Bane()
        {
            return Extensions.UnfriendlyUnits.Count(u => !u.HasAura("Miasma", true) && !u.HasAura("Bio", true) && !u.HasAura("Bio II", true) && u.Location.Distance(Core.Player.CurrentTarget.Location) <= 8);
        }

        public Composite ShadowFlare()
        {
            return new Decorator(r =>

                Actionmanager.HasSpell("Shadow Flare")
                && WindowSettings.lastspellused != "Shadow Flare"
                && !Extensions.DoubleCastPreventionDict.Contains(Core.Player.CurrentTarget, "Shadow Flare")
                && HasDots()
                && !Core.Player.HasAura("Shadow Flare")
                && ((!Core.Player.HasAura("Shadow Flare") && WindowSettings.ScholarSingleTargetFlare) || (Extensions.EnemiesNearTarget(5) >= WindowSettings.TargetsToAOE && !WindowSettings._dontaoeList.Contains(Core.Player.CurrentTarget.Name))),
  
                new Sequence(
                    new Action(r => WindowSettings.lastspellused = "Shadow Flare"),
                    new Sleep(500),
                    new Action(r => Actionmanager.DoActionLocation("Shadow Flare", Core.Player.CurrentTarget.Location)),
                    new Action(r => Extensions.UpdateDoubleCastDict("Shadow Flare", Core.Player.CurrentTarget))));

        }
        protected override Composite CreateCombat()
        {
            return new PrioritySelector(ctx => Core.Player.CurrentTarget,
                new Decorator(ctx => ctx != null,
                new PrioritySelector(
                new Decorator(ctx => ctx != null && BotManager.Current.IsAutonomous,
                    new PrioritySelector(
                        CommonBehaviors.MoveToLos(ctx => ctx as GameObject),
                        CommonBehaviors.MoveAndStop(ctx => (ctx as GameObject).Location, ctx => 20 + (ctx as GameObject).CombatReach, true, "Moving to unit")
						)
					),
                Casting.Cast(r => "Cleric Stance", r => WindowSettings.ToggleClericStance && !Core.Player.HasAura("Cleric Stance"), r => Core.Player, r => 2, r => false),

                new Decorator(r => Core.Player.IsCasting, new ActionAlwaysSucceed()),
                Combat.DoPVP(),
                new Decorator(ret =>
                {
                    if (!Core.Player.HasTarget)
                        return false;

                    if (!Core.Player.InCombat)
                        return false;

                    if (!Core.Player.CurrentTarget.CanAttack)
                        return false;

                    if ((WindowSettings.ScholarDoDPS && Core.Player.CurrentManaPercent >= WindowSettings.ScholarStopDPSMana) || !PartyManager.IsInParty || WindowSettings.SoloMode)
                        return true;

                    return false;

                }, new PrioritySelector(

                    Casting.Cast(r => "Energy Drain", r => WindowSettings.ScholarUseEnergyDrain && Core.Player.HasAura("Aetherflow") && Core.Player.CurrentManaPercent <= WindowSettings.ScholarEnergyDrainMana, r => Core.Player.CurrentTarget, r => 3, r => false),
                    Casting.Cast(r => "Bio II", r => !Core.Player.CurrentTarget.HasAura("Bio II", true, 3000), r => Core.Player.CurrentTarget, r => 3, r => true),
                    Casting.Cast(r => "Miasma", r => !Core.Player.CurrentTarget.HasAura("Miasma", true, 3000), r => Core.Player.CurrentTarget, r => 3, r => true),
                    Casting.Cast(r => "Bio", r => !Core.Player.CurrentTarget.HasAura("Bio", true, 3000), r => Core.Player.CurrentTarget, r => 3, r => true),

                    ShadowFlare(),

                    Casting.Cast(r => "Bane", r => WindowSettings.ScholarUseBane && Bane() >= WindowSettings.TargetsToAOE && !WindowSettings._dontaoeList.Contains(Core.Player.CurrentTarget.Name) && HasDots(), r => Core.Player.CurrentTarget, r => 2, r => false),
                    Casting.Cast(r => "Miasma II", r => WindowSettings.ScholarUseMiasmaII && MiasmaII() >= WindowSettings.TargetsToAOE, r => Core.Player, r => 3, r => true),               

                new Decorator(r =>
                {
                    if (PartyManager.IsInParty && PartyManager.VisibleMembers.FirstOrDefault(u => u.Name == Core.Player.Name).SyncdLevel < 50)
                        return true;

                    if (Core.Player.ClassLevel < 50)
                        return true;

                    if (HasDots())
                        return true;                      

                    return false;

                }, new PrioritySelector(

                Casting.Cast(r => "Ruin", r => true, r => Core.Player.CurrentTarget, r => 3, r => false),
                Casting.Cast(r => "Ruin II", r => true, r => Core.Player.CurrentTarget, r => 3, r => false))))))));
        }

        #endregion
    }
}